﻿using UnityEngine;
using System.Collections;
using UnityEditor;
using System;
using System.Runtime.InteropServices;
//using UnityEngine.Experimental.UIElements;
using UnityEditorInternal;
using System.IO.IsolatedStorage;
using System.Linq;

[Serializable]
public class TestDrag : EditorWindow
{
    private string path;
    Rect rect;
    [SerializeField]
    public GameObject source;
    public Texture myme;
    public Texture2D mymeScale;
    public Texture2D mymeScale2;
    Vector2 dragDir,drag2Direction;
    public Material mat;
    #region Preview 窗口模式
    PreviewRenderUtility m_PreviewUtility;
    GameObject m_PreviewInstance;
    Bounds m_PreviewBounds;
    bool m_isRenderDirty;
    bool m_isMoveDirty,m_isMoveDirty2;
    /// <summary>
    /// 之前用一开始用，这变量声明不够用，要用tex2D
    /// </summary>
    Texture m_preview;
    /// <summary>
    /// 之前用一开始用，这变量声明不够用，要用tex2D
    /// </summary>
    Texture m_preview2;
    int currDragTo;
    //float theScale =1 ;
    int picCount=2;
    float[] theScales;
    bool toggleOne = true;
    bool toggleSecond = false;
    int mSelectIndex;
    int singleWidth = 400;
    int singleHeight = 280;

    bool isCopyToClipboard;
    bool    isShowAfterExport;
    bool    isExport = true;
    #endregion
    [MenuItem("Window/图片2张合并")]
    private static void Init()
    {
        
        var win = EditorWindow.GetWindow(typeof(TestDrag));
        win.titleContent = new GUIContent("图片2张合并");
    }
    void Awake() {
        theScales = new float[2] { 1,1 };
    }
    private void InitPreview()
    {
        if (m_PreviewInstance == null) return;
        if (m_PreviewUtility == null)
        {
            // 参数true代表绘制场景内的游戏对象

            m_PreviewUtility = new PreviewRenderUtility(true);

            // 设置摄像机的一些参数
#if UNITY_2017_1_OR_NEWER
            m_PreviewUtility.cameraFieldOfView = 30f;
#endif


            // 创建预览的游戏对象

            CreatePreviewInstances();

        }

       

    }
    private void CreatePreviewInstances()

    {

        //DestroyPreviewInstances();
        //m_PreviewInstance = null;


        // 绘制场景上已经存在的游戏对象

        //m_PreviewInstance = GameObject.Find("ThirdPersonController");

        //m_PreviewInstance = _target.gameObject;

        //AddSingleGO(m_PreviewInstance);

#if UNITY_2017_1_OR_NEWER
        m_PreviewUtility.AddSingleGO(m_PreviewInstance);

#endif

        //修改 CreatePreviewInstances 方法，在最后添加获取包围盒代码：

        m_PreviewBounds = new Bounds(m_PreviewInstance.transform.position, Vector3.zero);

        GetRenderableBoundsRecurse(ref m_PreviewBounds, m_PreviewInstance);



    }
    public static void GetRenderableBoundsRecurse(ref Bounds bounds, GameObject go)
    {
        MeshRenderer meshRenderer = go.GetComponent(typeof(MeshRenderer)) as MeshRenderer;
        MeshFilter meshFilter = go.GetComponent(typeof(MeshFilter)) as MeshFilter;
        if (meshRenderer && meshFilter && meshFilter.sharedMesh)
        {
            if (bounds.extents == Vector3.zero)
            {
                bounds = meshRenderer.bounds;
            }
            else
            {
                // 扩展包围盒，以让包围盒能够包含另一个包围盒
                bounds.Encapsulate(meshRenderer.bounds);
            }
        }
        SkinnedMeshRenderer skinnedMeshRenderer = go.GetComponent(typeof(SkinnedMeshRenderer)) as SkinnedMeshRenderer;
        if (skinnedMeshRenderer && skinnedMeshRenderer.sharedMesh)
        {
            if (bounds.extents == Vector3.zero)
            {
                bounds = skinnedMeshRenderer.bounds;
            }
            else
            {
                bounds.Encapsulate(skinnedMeshRenderer.bounds);
            }
        }
        foreach (Transform transform in go.transform)
        {
            GetRenderableBoundsRecurse(ref bounds, transform.gameObject);
        }
    }
    //void OnPreviewGUI() {
    //    Debug.Log("on preview");
    //}
    void OnGUI()
    {
        //无用
        InitPreview();

        //暂无用（测试）的按钮
        //EditorGUILayout.BeginHorizontal();
        ////2017后必须指定参数：allowSceneObjects == true
        //source = EditorGUILayout.ObjectField("hiahia", source, typeof(GameObject), true) as GameObject;
        //myme = (Texture)EditorGUILayout.ObjectField("hehe", myme, typeof(Texture), true);//注意类型转换
        //EditorGUILayout.EndHorizontal();
        //m_PreviewInstance = EditorGUILayout.ObjectField("绘制对象", m_PreviewInstance, typeof(GameObject), true) as GameObject;
        //mat = EditorGUILayout.ObjectField("视图控制Mat", mat,typeof(Material),true) as Material;
        ////EditorGUI.PropertyField()
        EditorGUILayout.LabelField("测试路径");
        rect = EditorGUILayout.GetControlRect(GUILayout.Width(400));

        path = EditorGUI.TextField(rect, path);
        //////////////////////////
        OnControlBar();
        ///////////////////////////
        ///

        #region Drag & Drop
        rect = EditorGUILayout.GetControlRect(GUILayout.Width(400), GUILayout.Height(280));
        //EditorGUI.DrawRect(rect, Color.yellow);

        Rect rect2 = new Rect(400 + 10, rect.y, 400, 280);
        //EditorGUI.DrawPreviewTexture(rect,);
        //2017后EventType.DragUpdated不能小写咯
        if (Event.current.type == EventType.DragUpdated)
        {
            if (rect.Contains(Event.current.mousePosition))
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
                {
                    path = DragAndDrop.paths[0];
                    currDragTo = 1;
                }
                Debug.Log(Event.current.type);
            }
            else if (rect2.Contains(Event.current.mousePosition))
            {
                DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)
                {
                    path = DragAndDrop.paths[0];
                    currDragTo = 2;
                }


            }

        }
        else if (Event.current.type == EventType.DragExited)//在dragPerform之后还会触发一次，只能实现去除 mask 了
        {
            path = "";
            Debug.Log(Event.current.type);
        }
        else if (Event.current.type == EventType.DragPerform)
        {
            if (currDragTo == 2)
            {
                LoadToCache(path, (tex) => {

            
                    mymeScale2 = TextureUtils.TextureToTexture2D(tex);
                    //拖拉2事件    
                    toggleOne = false;
                    toggleSecond = true;
                    m_isRenderDirty = true;
                    UpdateSectionEvent();

                });
            }
            else if (currDragTo == 1)
            {
                LoadToCache(path, (tex) =>
                {
                    
                    mymeScale = TextureUtils.TextureToTexture2D(tex);
                    //tuola 1shijian
                    //拖拉1事件
                    toggleOne = true;
                    toggleSecond = false;
                    m_isRenderDirty = true;
                    UpdateSectionEvent();
                });
            }
            Debug.LogWarning("drag 生效");
        }
        else if (Event.current.type == EventType.MouseUp)
        {
            //还会触发2次。。。。
            Debug.Log("mouse up");
        }

#endregion

        #region render 点击select后，或者drag重新导入图片

        //render1
        if (m_isRenderDirty)
        {
           
            Texture2D basePic = GetTheBasePic(mSelectIndex);
            if (basePic != null)
            {
                float selectScale = GetTheScale(mSelectIndex);
                Texture showPic = GetTheShowPic(mSelectIndex);

                //放大缩小图片（底图）
                //if (selectScale != 1)
                //{
                //    //mymeScale = TextureUtils.ScaleTexture(TextureUtils.TextureToTexture2D(myme), selectScale);

                //}
                //else
                //{
                //    mymeScale = TextureUtils.TextureToTexture2D(myme);
                //}
                //不能这么赋值????TODO:w为什么不能这么赋值？？？？
                //                basePic = TextureUtils.ScaleTexture(basePic, selectScale);

                //TODO;fan放大，缩小时按中心点缩放。。。。。

                if (mSelectIndex == 1)
                {
                    var mymeScaleTemp = TextureUtils.ScaleTexture(mymeScale, selectScale);
                    m_preview = GetCurrentTexture(mymeScale, singleWidth, singleHeight, Mathf.FloorToInt(dragDir.x), Mathf.FloorToInt(-dragDir.y));
                }
                else
                {
                    var mymeScale2Temp = TextureUtils.ScaleTexture(mymeScale2, selectScale);
                    m_preview2 = GetCurrentTexture(mymeScale2Temp, singleWidth, singleHeight, Mathf.FloorToInt(drag2Direction.x), Mathf.FloorToInt(-drag2Direction.y));
                    //不能这么赋值
                    //showPic = GetCurrentTexture(basePic, 800, 600, Mathf.FloorToInt(currDir.x), Mathf.FloorToInt(-currDir.y));
                }
                //GUI.DrawTexture(rect,myme,)
            }
        }

        #endregion

        /////////////////////////////
        #region 拖动的实现（图片移动）
        ////////////////////////////
        // 上下左右的旋转(必须，写在Event.current.type != EventType.Repaint ，的前面
        var currDir = Drag2D(dragDir, rect, 580);
        //if (Event.current.type != EventType.Repaint)
        //{
        //    return;
        //}
        if (currDir != dragDir)
        {
            m_isMoveDirty = true;
            dragDir = currDir;
        }

        var currDrag2 = Drag2D(drag2Direction, rect2, 580);
        if (currDrag2 != drag2Direction)
        {
            m_isMoveDirty2 = true;
            drag2Direction = currDrag2;
        }
        //TODO:暂时只能分开处理
        if (m_isMoveDirty)
        {
            float selectScale1 = GetTheScale(1);
            Texture2D mymeScale2Temp = null;
            mymeScale2Temp = TextureUtils.ScaleTexture(mymeScale, selectScale1);
            m_preview = GetCurrentTexture(mymeScale2Temp, singleWidth, singleHeight, Mathf.FloorToInt(currDir.x), Mathf.FloorToInt(-currDir.y));
        }
        else if (m_isMoveDirty2)
        {
            float selectScale2 = GetTheScale(2);
            Texture2D mymeScale2Temp = null;

            mymeScale2Temp = TextureUtils.ScaleTexture(mymeScale2, selectScale2);
            m_preview2 = GetCurrentTexture(mymeScale2Temp, singleWidth, singleHeight, Mathf.FloorToInt(currDrag2.x), Mathf.FloorToInt(-currDrag2.y));
        }
        m_isRenderDirty = false;
        m_isMoveDirty = false;


  

        //if (m_preview == null)
        //    m_preview = GetCurrentTexture(myme, 800, 600);

        if (toggleOne)
        {
            EditorGUIUtility.DrawColorSwatch(new Rect(rect.x - 2, rect.y - 1, rect.width + 4, rect.height + 4), Color.yellow);
        }
        else if (toggleSecond)
        {
            EditorGUIUtility.DrawColorSwatch(new Rect(rect2.x - 2, rect2.y - 2, rect2.width + 4, rect2.height + 4), Color.yellow);
        }
        if(m_preview!=null)
            EditorGUI.DrawPreviewTexture(rect, m_preview, null, ScaleMode.ScaleToFit);//现在面积是一样的，所以ScaleToFit无效果
        //render2
        if(m_preview2!=null)
            EditorGUI.DrawPreviewTexture(rect2, m_preview2, null, ScaleMode.ScaleToFit);

        #endregion

        GUILayout.Space(5);
        //isCopyToClipboard = GUILayout.Toggle(isCopyToClipboard, "复制到剪切板");
        //isShowAfterExport = GUILayout.Toggle(isShowAfterExport, "导出后预览");
        //isExport = GUILayout.Toggle(isExport, "是否导出");
        
        if (GUILayout.Button("导出"))
        {
            string extension = "图像文件|*.png";
            string selPath = EditorUtility.SaveFilePanel("", Application.dataPath + "/../","1_2_merge.png", extension);
         
            if (string.IsNullOrEmpty(selPath))
                return;

            Texture2D texCanvas = new Texture2D(singleWidth * 2, singleHeight);
            Color[] emptyColors = TextureUtils.CreateColors(texCanvas.GetPixels().Length);
            texCanvas.SetPixels(emptyColors);
            SaveRefPreviewTex();
            
            texCanvas = TextureUtils.MergeTextureByTransform(texCanvas, TextureUtils.T2D( m_preview2), singleWidth, 0);
            texCanvas = TextureUtils.MergeTextureByTransform(texCanvas, TextureUtils.T2D(m_preview), 0, 0);
            m_preview2 = texCanvas;
            TextureUtils.SaveTextureToFile(texCanvas, selPath);
        }

        #region 预览Editor preview绘制的实现，没调通
        //Preview 预览绘制（暂时EditorWindow里面没调通)
        //if (m_PreviewInstance!=null &&  m_PreviewUtility != null)
        //{

        //    Quaternion quaternion = Quaternion.Euler(new Vector3(45, 45, 0));

        //    float num = Mathf.Max(m_PreviewBounds.extents.magnitude, 0.0001f);
        //    float num2 = num * 3.8f;
        //    Vector3 position = m_PreviewBounds.center - quaternion * (Vector3.forward * num2);
        //    m_PreviewUtility.BeginPreview(rect, null);
        //    Camera camera = m_PreviewUtility.camera;
        //    //camera.transform.position = m_PreviewInstance.transform.position + new Vector3(0, 5f, 3f);
        //    //camera.transform.LookAt(m_PreviewInstance.transform);
        //    camera.transform.position = position;
        //    camera.transform.rotation = quaternion;
        //    camera.nearClipPlane = num2 - num * 1.1f;
        //    camera.farClipPlane = num2 + num * 1.1f;

        //    SetEnabledRecursive(m_PreviewInstance, true);
        //    camera.Render();
        //    SetEnabledRecursive(m_PreviewInstance, false);
        //    m_PreviewUtility.EndAndDrawPreview(rect);
        //}
        #endregion

    }
    void SaveRefPreviewTex() {
        GetTheShowPic(1);
        GetTheShowPic(2);
    }
    Texture GetTheShowPic(int index) {
        if (index == 1) {
            if (m_preview == null)
                m_preview = TextureUtils.CreateEmptyTexture();
          
            return m_preview; 
        }
        else {
            if (m_preview2 == null)
                m_preview2 = TextureUtils.CreateEmptyTexture();
            return m_preview2; 
        
        }
    }
    /// <summary>
    /// 暂时的获取方法，之后要改
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    Texture2D GetTheBasePic(int index) {
        if (index == 1)
        {
            return mymeScale;
        }
        else
        {
            return mymeScale2;
        }
    }
    float GetTheScale(int index) {
        return theScales[index - 1];
    }
    void SetTheScale(int index, float scale)
    {
        theScales[index - 1] = scale;
    }
    void UpdateSectionEvent() {
        if (toggleOne == true)
        {
            mSelectIndex = 1;
            dragDir = Vector2.zero;
        }
        else if (toggleSecond == true)
        {
            mSelectIndex = 2;
            drag2Direction = Vector2.zero;
        }
    }
    void OnControlBar() {
        GUILayout.BeginHorizontal();

        if (GUILayout.Button("还原"))
        {
            if (toggleOne)
            {
                SetTheScale(1, 1);
            }
            else
            {
                SetTheScale(2, 1);
            }
            m_isRenderDirty = true;
        }
        //toggleOne = GUILayout.Toggle(toggleOne, "1");
        //toggleSecond = GUILayout.Toggle(toggleSecond, "2");
        //if (GUI.changed)
        //{
        //    //TODO:看看toggle group如何做
            
        //}
        if (GUILayout.Button("select"))
        {
            toggleOne = !toggleOne;
            toggleSecond = !toggleSecond;
            UpdateSectionEvent();
            
        }
        if (GUILayout.Button("+"))
        {
            if (toggleOne)
            {
                float theScale = GetTheScale(1);
                SetTheScale(1, theScale + 0.1f);
            }
            else {
                float theScale = GetTheScale(2);
                SetTheScale(2, theScale + 0.1f);
            }

            
            
            m_isRenderDirty = true;
        }
        if (GUILayout.Button("-"))
        {
            if (toggleOne)
            {
                float theScale = GetTheScale(1);
                SetTheScale(1, theScale - 0.1f);
            }
            else
            {
                float theScale = GetTheScale(2);
                SetTheScale(2, theScale - 0.1f);
            }

            m_isRenderDirty = true;
        }
        GUILayout.EndHorizontal();
    }
    void LoadToCache(string path, Action<Texture> cb)
    {
        EditorCoroutineRunner.StartCoroutine(TextureUtils.LoadTexture(path, cb));
        //var tex = AssetDatabase.LoadAssetAtPath<Texture>(path);
        //cacheTex = tex;
    }
    Texture GetCurrentTexture(Texture tex,int width,int height,int offsetX = 0,int offsetY = 0) {
        tex = TextureUtils.CopyTexture(tex, width, height,offsetX,offsetY);
        
        return tex;
    }
    public static void SetEnabledRecursive(GameObject go, bool enabled)
    {
        Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>();
        for (int i = 0; i < componentsInChildren.Length; i++)
        {
            Renderer renderer = componentsInChildren[i];
            renderer.enabled = enabled;
        }
    }

    void OnImageLayout() { 
        
    }

    //void Update()
    //{
    //    if (Input.GetMouseButton(1))
    //    {
    //        Debug.Log("button 1");
    //    }

    //}
    /// <summary>
    /// 
    /// </summary>
    /// <param name="scrollPosition"></param>
    /// <param name="position"></param>
    /// <returns>delta</returns>
    public static Vector2 Drag2D(Vector2 scrollPosition, Rect position,uint yAxisLimit = 90)
    {
        int controlID = GUIUtility.GetControlID("Slider".GetHashCode(), FocusType.Passive);
        Event current = Event.current;
        switch (current.GetTypeForControl(controlID))
        {
            case EventType.MouseDown:
                if (position.Contains(current.mousePosition) && position.width > 50f)
                {
                    GUIUtility.hotControl = controlID;
                    current.Use();
                    // 让鼠标可以拖动到屏幕外后，从另一边出来
                    EditorGUIUtility.SetWantsMouseJumping(1);
                }
                break;
            case EventType.MouseUp:
                if (GUIUtility.hotControl == controlID)
                {
                    GUIUtility.hotControl = 0;
                }
                EditorGUIUtility.SetWantsMouseJumping(0);
                break;
            case EventType.MouseDrag:
                if (GUIUtility.hotControl == controlID)
                {
                    // 按住 Shift 键后，可以加快旋转
                    scrollPosition -= current.delta * (float)((!current.shift) ? 1 : 3) / Mathf.Min(position.width, position.height) * 140f;
                    scrollPosition.y = Mathf.Clamp(scrollPosition.y, -yAxisLimit, yAxisLimit);
                    current.Use();
                    GUI.changed = true;
                }
                break;
        }
        return scrollPosition;
    }
}
